home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / DDJ0192.ARJ / DISPLAY.C < prev    next >
C/C++ Source or Header  |  1991-09-04  |  7KB  |  323 lines

  1. /****************************************************************
  2.  *                                                              *
  3.  * DISPLAY.C general purpose Microsoft C text display library   *
  4.  * See also DISPLAY.H DIRPICK.C, and HISTO.C                    *
  5.  * Al Williams                                                  *
  6.  *                                                              *
  7.  ****************************************************************/
  8. #include <stdio.h>
  9. #include <dos.h>
  10. #include <string.h>
  11. #include <stdarg.h>
  12. #include "display.h"
  13.  
  14. /* global variable sets color of output */
  15. int color=7;
  16.  
  17. /* primary colors for color monitor (see display.h) */
  18. int colors[4]={ 0x1e, 0x70, 0x1c, 0x7e };
  19.  
  20. /* 1=mono monitor, 0=color, -1=unknown */
  21. int mono=-1;
  22.  
  23. /* set video mode and detect mono monitor
  24.    this should always be called first */
  25. void vidmode()
  26.   {
  27.   union REGS r;
  28.   if (mono<0)
  29.     {
  30.     r.h.ah=0xf;
  31.     int86(0x10,&r,&r);
  32.     mono=r.h.al==7;
  33.     }
  34.   r.x.ax=mono?7:3;
  35.   int86(0x10,&r,&r);
  36.   r.x.ax=0x500;
  37.   int86(0x10,&r,&r);
  38.   }
  39.  
  40.  
  41.  
  42. /* goto point x,y (from 0-79 and 0-24) */
  43. void goxy(int x,int y)
  44.   {
  45.   union REGS r;
  46.   r.h.ah=2;
  47.   r.h.dh=y;
  48.   r.h.dl=x;
  49.   r.h.bh=0;
  50.   int86(0x10,&r,&r);
  51.   }
  52.  
  53.  
  54. /* clear screen region */
  55. void clears(int x0, int y0,int x1,int y1)
  56.   {
  57.   union REGS r;
  58.   r.x.ax=0x600;
  59.   r.h.bh=color;
  60.   r.h.ch=y0;
  61.   r.h.cl=x0;
  62.   r.h.dh=y1;
  63.   r.h.dl=x1;
  64.   int86(0x10,&r,&r);
  65.   goxy(0,0);
  66.   }
  67.  
  68. /* get x,y position */
  69. void getxy(int *x,int *y)
  70.   {
  71.   union REGS r;
  72.   r.h.ah=3;
  73.   r.h.bh=0;
  74.   int86(0x10,&r,&r);
  75.   *x=r.h.dl;
  76.   *y=r.h.dh;
  77.   }
  78.  
  79. /* write count characters
  80.    -- handle \r, \n, backspace, and \a
  81.    updates the cursor if count==1 (w/o line wrap)
  82.    otherwise, the cursor doesn't move */
  83. void writecc(int c,int count)
  84.   {
  85.   union REGS r;
  86. /* PS/2 BIOS tries to print 0 characters! */
  87.   if (count<=0) return;
  88. /* if bell character... */
  89.   if (c=='\a')
  90.     {
  91. /* use function 0eH to do count bells */
  92.     while (count--)
  93.       {
  94.       r.x.ax=0xe00|'\a';
  95.       r.x.bx=0;
  96.       int86(0x10,&r,&r);
  97.       }
  98.     return;
  99.     }
  100. /* if regular character (not \n or \r or bs) */
  101.   if (c!='\n'&&c!='\r'&&c!=8)
  102.     {
  103. /* print regular character */
  104.     r.h.ah=9;
  105.     r.h.al=c;
  106.     r.h.bh=0;
  107.     r.h.bl=color;
  108.     r.x.cx=count;
  109.     int86(0x10,&r,&r);
  110. /* if count isn't 1 return else do cursor update
  111.    NOTE: \n \r always update cursor */
  112.     if (count!=1) return;
  113.     }
  114. /* get cursor position */
  115.   r.h.ah=3;
  116.   r.h.bh=0;
  117.   int86(0x10,&r,&r);
  118. /* if \r, zero x coordinate
  119.    Note that 100 \r's is the same as 1 */
  120.   if (c=='\r')
  121.     r.h.dl=0;
  122. /* if \n, increment y coordinate by count */
  123.   else if (c=='\n')
  124.     r.h.dh+=count;
  125. /* if backspace back up by count or to start of line */
  126.   else if (c==8)
  127.     r.h.dl-=r.h.dl>count?count:r.h.dl;
  128.   else
  129. /* bump x coordinate. Assume it won't wrap over */
  130.     r.h.dl++;
  131.   r.h.ah=2;
  132.   int86(0x10,&r,&r);
  133.   }
  134.  
  135. /* write a string using writec, a writecc macro
  136.    (see display.h) */
  137. void writes(char *s)
  138.   {
  139.   while (*s) writec(*s++);
  140.   }
  141.  
  142. /* printf using writecc max length 99 */
  143. int printfc(char *fmt,...)
  144.   {
  145.   int rc;
  146.   char outbuf[100];
  147.   va_list aptr;
  148.   va_start(aptr,fmt);
  149.   rc=vsprintf(outbuf,fmt,aptr);
  150.   writes(outbuf);
  151.   return rc;
  152.   }
  153.  
  154.  
  155. /* prompt for single key @ coordinates x,y
  156.    use str as prompt, resp is valid keys, pcolor
  157.    is the color to use (0 for same color). Alpha characters
  158.    in resp should be upper case. If resp is "" then all
  159.    characters are valid. If resp is NULL then any alpha
  160.    character is valid.
  161.  
  162.    returns:
  163.    -1 if ESC pressed
  164.    index of character if resp is valid
  165.    character if resp is NULL or ""
  166.    */
  167. int prompt_at(int x, int y, char *str,char *resp,int pcolor)
  168.   {
  169.   int ocolor,c;
  170.   char *index;
  171.   goxy(x,y);
  172.   ocolor=color;
  173.   if (pcolor) color=pcolor;
  174. /* clear to end of line */
  175.   clreol();
  176.   writes(str);
  177.   while (1)
  178.     {
  179. /* get key */
  180.     c=getch();
  181.     if (!c)
  182.       {
  183. /* ignore extended keys */
  184.       getch();
  185.       continue;
  186.       }
  187. /* if esc quit */
  188.     if (c==27) break;
  189. /* shift upper */
  190.     c=toupper(c);
  191. /* if resp in not null, check it */
  192.     if (resp&&(index=strchr(resp,c))) break;
  193. /* if resp is null, check for alpha */
  194.     if (resp==NULL&&isalpha(c)) break;
  195. /* if resp=="" then anything is OK */
  196.     if (resp&&!*resp) break;
  197.     }
  198.   color=ocolor;
  199.   goxy(x,y);
  200.   clreol();
  201.   curshide();
  202.   return c==27?-1:resp&&*resp?index-resp:c;
  203.   }
  204.  
  205.  
  206.  
  207. /* prompt for input @x,y. Prompt with promptstr
  208.    valid is a string of valid input characters
  209.    (if NULL, all characters are OK., clr is the color (0 for same),
  210.    len is the input length, buf is the buffer (should be
  211.    at least len+1 long, and help is an optional help
  212.    string (use NULL for the default help)
  213.  
  214.    returns: -1 if ESC
  215.             # of characters input otherwise
  216.  
  217.    You can use the backspace key to edit entries */
  218.  
  219. int ask_at(int x, int y, char *promptstr,char *valid,
  220.       int clr,int len,char *buf,char *help)
  221.   {
  222.   int count=0,c,ocolor=color;
  223.   char *bp=buf;
  224. /* clear buffer */
  225.   memset(buf,0,len+1);
  226. /* set color, goto input line, and clear it */
  227.   if (clr) color=clr;
  228.   goxy(x,y);
  229.   clreol();
  230. /* write prompt */
  231.   writes(promptstr);
  232.  
  233. /* main loop */
  234.   while (1)
  235.     {
  236. /* get a character. Extended keys are <0 */
  237.     c=getch();
  238.     if (!c) c=-getch();
  239. /* handle backspace */
  240.     if (c==8)
  241.       {
  242.       if (bp!=buf)
  243.         {
  244.         bp--;
  245.         writec(8);
  246.         writec(' ');
  247.         writec(8);
  248.         *bp='\0';
  249.         count--;
  250.         }
  251.       continue;
  252.       }
  253. /* Escape or enter ends input */
  254.     if (c=='\r'||c==27)
  255.       {
  256. /* restore color */
  257.       color=ocolor;
  258. /* clear line */
  259.       goxy(x,y);
  260.       clreol();
  261.       curshide();
  262. /* return */
  263.       return c==27?-1:count;
  264.       }
  265. /* If F1 give help */
  266.     if (c==-59)
  267.       {
  268.       vidsave();
  269.       prompt(help?help:
  270.       " Use <ENTER> to accept, <ESC> to quit, <Backspace>"
  271.          " to correct.","",SOCOLOR);
  272.       vidrestore();
  273.       continue;
  274.       }
  275. /* ignore other extended keys (c<0) or regular keys if
  276.    at input limit (count==len) */
  277.     if (count==len||c<0) continue;
  278. /* if not valid character, ignore */
  279.     if (valid&&!strchr(valid,c)) continue;
  280. /* echo input character */
  281.     writec(c);
  282. /* store in buffer */
  283.     *bp++=c;
  284. /* update count */
  285.     count++;
  286.     }
  287.   }
  288.  
  289.  
  290. /**********************************************
  291.  routines to save and restore the video context
  292.  */
  293.  
  294. /* places to save things */
  295. static char vbuf[4096];
  296. static int save_xy,save_color;
  297.  
  298. /* save video */
  299. void vidsave()
  300.   {
  301.   union REGS r;
  302.   save_color=color;
  303.   r.h.ah=3;
  304.   r.h.bh=0;
  305.   int86(0x10,&r,&r);
  306.   save_xy=r.x.dx;
  307.   memcpy((void *)vbuf,(void *)(mono?0xb0000:0xb8000),4096);
  308.   }
  309.  
  310. /* restore video */
  311. void vidrestore()
  312.   {
  313.   union REGS r;
  314.   memcpy((void *)(mono?0xb0000:0xb8000),(void *)vbuf,4096);
  315.   color=save_color;
  316.   r.h.ah=2;
  317.   r.h.bh=0;
  318.   r.x.dx=save_xy;
  319.   int86(0x10,&r,&r);
  320.   }
  321.  
  322.  
  323.